/** 
 * MacWindowTitle.java
 * @author Lex
 * 2007-9-7 ����04:03:26
 */
package lex.title.mac;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import javax.swing.*;
import javax.swing.plaf.ButtonUI;
import lex.WindowDecoration;
import lex.title.MaximizeRestoreButton;
import lex.title.WindowButton;
import lex.title.WindowButtonUI;
import lex.title.basic.BasicWindowTitle;
import lex.title.basic.PrimalWindowTitle;
import lex.util.FvwmLayout;
import lex.util.ImageCache;
import lex.util.Utilities;

public class MacWindowTitle extends BasicWindowTitle {
	// using in layout
	MaximizeRestoreButton maximizeButton;
	JButton minimizeButton;
	JButton closeButton;
	JButton menuButton;
	// =============================
	JMenuBar systemMenuBar;
	JPopupMenu menu;

	public MacWindowTitle(JRootPane rootPane) {
		super(rootPane);
		if (this.isNoneDecoration())
			return;
		// ==============================
		this.setLayout(new FvwmLayout(5, 7, 7));
		this.add("left 0 center", this.getCloseButton());
		this.add("right 0 center", this.getMenuButton());
		if (true == isFrame()) {
			this.add("left center 1", this.getMinimizeButton());
			this.add("left center 2", getMaximizeRestoreButton());
		}
	}

	// ========================================
	// Button Getters
	// ========================================
	protected JButton getCloseButton() {
		if (null == this.closeButton) {
			ImageCache ic = ImageCache.getInstance();
			ButtonUI ui = new WindowButtonUI(ic.getMacImage("close-normal.png"), ic.getMacImage("close-rollover.png"),
					ic.getMacImage("close-pressed.png"), ic.getMacImage("close-disabled.png"));
			closeButton = new WindowButton(ui);
			closeButton.setAction(this.getCloseAction());
		}
		return this.closeButton;
	}

	protected MaximizeRestoreButton getMaximizeRestoreButton() {
		if (null == this.maximizeButton) {
			ImageCache ic = ImageCache.getInstance();
			ButtonUI max = new WindowButtonUI(ic.getMacImage("maximize-normal.png"), ic.getMacImage("maximize-rollover.png"),
					ic.getMacImage("maximize-pressed.png"), ic.getMacImage("maximize-disabled.png"));
			ButtonUI restore = new WindowButtonUI(ic.getMacImage("restore-normal.png"), ic.getMacImage("restore-rollover.png"),
					ic.getMacImage("restore-pressed.png"), ic.getMacImage("restore-disabled.png"));
			maximizeButton = new MaximizeRestoreButton(max, restore);
			maximizeButton.setActions(getMaximizeAction(), getRestoreAction());
		}
		return this.maximizeButton;
	}

	protected JButton getMinimizeButton() {
		if (null == this.minimizeButton) {
			ImageCache ic = ImageCache.getInstance();
			ButtonUI ui = new WindowButtonUI(ic.getMacImage("minimize-normal.png"), ic.getMacImage("minimize-rollover.png"),
					ic.getMacImage("minimize-pressed.png"), ic.getMacImage("minimize-disabled.png"));
			minimizeButton = new WindowButton(ui);
			minimizeButton.setAction(this.getMinimizeAction());
		}
		return this.minimizeButton;
	}

	protected JButton getMenuButton() {
		if (null == this.menuButton) {
			ImageCache ic = ImageCache.getInstance();
			ButtonUI ui = new WindowButtonUI(ic.getMacImage("menu-normal.png"), ic.getMacImage("menu-rollover.png"),
					ic.getMacImage("menu-pressed.png"), ic.getMacImage("menu-disabled.png"));
			menuButton = new WindowButton(ui);
			menuButton.setAction(new AbstractAction() {
				public void actionPerformed(ActionEvent e) {
					JComponent c = MacWindowTitle.this;
					JPopupMenu p = getMenu();
					int y = c.getHeight();
					if (true == isLeftToRight())
						p.show(c, c.getWidth() - p.getWidth(), y);
					else
						p.show(c, 0, y);
				}
			});
		}
		return this.menuButton;
	}

	protected JPopupMenu getMenu() {
		if (null == this.menu) {
			menu = new JPopupMenu();
			menu.add(this.getRestoreAction());
			menu.add(this.getMinimizeAction());
			menu.add(this.getMaximizeAction());
			menu.addSeparator();
			menu.add(this.getCloseAction());
		}
		return menu;
	}

	protected void paintComponent(Graphics g) {
		if (getFrame() != null) {
			setState(getFrame().getExtendedState());
		}
		Window window = this.getWindow();
		boolean leftToRight = true;
		boolean active = true;
		if (null != window) {
			leftToRight = window.getComponentOrientation().isLeftToRight();
			active = window.isActive();
		}
		int width = getWidth();
		int height = getHeight();
		Graphics2D g2 = (Graphics2D) g;
		Object oldAntiAliasingValue = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		drawBackground(g, active, width, height);
		int titleLength = 0;
		int xOffset = leftToRight ? 2 : (width - 2);
		String frameTitle = getTitle();
		if (frameTitle != null) {
			Font f = getFont();
			g.setFont(f);
			int osFontOffset = f.getFamily().equals(WindowDecoration.fontName) ? 2 : 0;
			FontMetrics fm = g.getFontMetrics();
			titleLength = fm.stringWidth(frameTitle);
			int titleW = 0;
			Rectangle r = new Rectangle(0, 0, 0, 0);
			{
				if (getMaximizeAction().isEnabled()) {
					r = maximizeButton.getBounds();
				} else if (getMinimizeAction().isEnabled()) {
					r = minimizeButton.getBounds();
				} else if (getCloseAction().isEnabled()) {
					r = closeButton.getBounds();
				}
				Rectangle menu = new Rectangle(0, 0, 0, 0);
				if (menuButton != null) {
					menu = menuButton.getBounds();
				}
				if (menu.x == 0) {
					menu.x = window.getWidth() - window.getInsets().right;
				}
				xOffset = r.x + r.width + 2;
				titleW = menu.x - xOffset;
			}
			int startTitleLength = fm.stringWidth(frameTitle);
			frameTitle = Utilities.clipStringIfNecessary(fm, frameTitle, titleW);
			titleLength = fm.stringWidth(frameTitle);
			if (titleLength == startTitleLength) {
				xOffset += (titleW - titleLength) / 2;
			}
			FontRenderContext frc = g2.getFontRenderContext();
			LineMetrics lm = f.getLineMetrics(frameTitle, frc);
			int yOffset = ((height - Math.round(lm.getHeight())) / 2) + Math.round(lm.getAscent()) + osFontOffset;
			if (!leftToRight) {
				xOffset -= titleLength;
			}
			if (active) {
				{
					g.setColor(Color.black);
					Frame _frame = null;
					Dialog _dialog = null;
					Image image = null;
					Window w = this.getWindow();
					if (w instanceof Frame) {
						_frame = (Frame) w;
						image = _frame.getIconImage();
					} else {
						_dialog = (Dialog) w;
						if (_dialog.getParent() != null) {
							if (_dialog.getParent() instanceof Frame) {
								image = ((Frame) _dialog.getParent()).getIconImage();
							}
						}
					}
					if (image != null) {
						xOffset += 10;
						g.drawImage(image, xOffset - 20, 3, PrimalWindowTitle.IMAGE_WIDTH, PrimalWindowTitle.IMAGE_HEIGHT, null);
					} else {
						Icon icon = UIManager.getIcon("InternalFrame.pantherIcon");
						if (icon != null) {
							xOffset += 10;
							icon.paintIcon(this, g, xOffset - 20, 3);
						}
					}
				}
				g.drawString(frameTitle, xOffset, yOffset - 1);
				xOffset += (leftToRight ? (titleLength + 2) : (-2));
			} else {
				// for an inactive window
				Frame _frame = null;
				Dialog _dialog = null;
				Image image = null;
				Window w = this.getWindow();
				if (w instanceof Frame) {
					_frame = (Frame) w;
					image = _frame.getIconImage();
				} else {
					_dialog = (Dialog) w;
					if (_dialog.getParent() != null) {
						if (_dialog.getParent() instanceof Frame) {
							image = ((Frame) _dialog.getParent()).getIconImage();
						}
					}
				}
				if (image != null) {
					xOffset += 10;
					g.drawImage(image, xOffset - 20, 3, PrimalWindowTitle.IMAGE_WIDTH, PrimalWindowTitle.IMAGE_HEIGHT, null);
				} else {
					Icon icon = UIManager.getIcon("InternalFrame.pantherIconInactive");
					if (icon != null) {
						xOffset += 10;
						icon.paintIcon(this, g, xOffset - 20, 3);
					}
				}
				g.setColor(new Color(115, 115, 115));
				g.drawString(frameTitle, xOffset, yOffset - 1);
				xOffset += (leftToRight ? (titleLength + 2) : (-2));
			}
		}
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAntiAliasingValue);
	}

	private void drawBackground(Graphics g, boolean active, int w, int h) {
		Graphics2D g2 = (Graphics2D) g;
		GradientPaint grad = active ? new GradientPaint(0, 0, new Color(238, 238, 238), 0, h - 1, new Color(192, 192, 192)) : new GradientPaint(0, 0,
				new Color(230, 230, 230), 0, h - 1, new Color(202, 202, 202));
		g2.setPaint(grad);
		g2.fillRect(0, 0, w, h - 1);
		g2.setColor(new Color(198, 198, 198));
		g2.drawLine(0, 0, w - 1, 0);
		g2.setColor(Color.WHITE);
		g2.drawLine(0, 1, w - 1, 1);
		g2.setColor(new Color(147, 147, 147));
		g2.drawLine(0, h - 1, w, h - 1);
	}
}
